/*
 * connect_pool.h
 *
 *  Created on: 2012-7-5
 *      Author: ThinkPad
 */

#ifndef CONNECT_POOL_H_
#define CONNECT_POOL_H_


#include "io_buf.h"
#include "user_token.h"
#include "net_event.h"
#include "link_list.h"

/*
*NETPROTOCL define
*/
enum NETPROTOCL{NET_TCP,NET_UDP,NET_RAW_UDP,NET_RAW_TCP};
/*
*sock active state
*/
enum SOCKET_STATE
{
        S_CLOSE,
        S_ACTIVE
};

/*
*sock list index
*/
enum SOCKET_LIST_INDEX
{
        S_FREE_LIST,
        S_CONN_LIST,
        S_WAIT_LIST
};

/*
*Net Error Code
*/
enum NET_ERROR_CODE
{
        INVALID_ERROR,
        CONNECT_ERROR,
        RECV_ERROR,
        SEND_ERROR,
        TRANSMIT_ERROR,
        OP_TIMEOUT,
        CLIENT_CLOSED,
        CLIENT_ERROR,
        SERVER_ERROR,
        NOT_ENOUGH_MEMORY_ERROR,
        ADMIN_FORCE_CLOSE
};
/*
*
*io opration action
*
*/
enum OPRATION
{
    OP_INVALID,
    OP_ACCEPT,
    OP_ACCEPT_COMPLETE,
    OP_CONNECT,
    OP_CONNECT_COMPLETE,
    OP_RECV,
    OP_RECV_COMPLETE,
    OP_SEND,
    OP_SEND_COMPLETE,
    OP_TRANSFILE,
    OP_TRANSFILE_COMPLETE
};

/*
 * connectoin struct
 */

struct netconnection
{
    int                 sockfd;            /*socket fd*/
    OPRATION            OperationType;     /*last operation action type*/
    EVENT               CurrentEvent;      /*current event*/
    SOCKET_STATE        socket_state;      /*socket active state flag*/
    buf_chunk           *iobuf;            /*io user buffer*/
    bool                ctr_flag;          /*epoll events ctr flag*/
    uint32_t            events;			   /*epoll register events*/

    time_t              timeLastAction;     /*last post operation  time*/
    time_t              timeConnBegin;      /*connection begin  time*/

    NET_ERROR_CODE      erroCode;           /*sockt error code*/
    NETPROTOCL          net_protocl;        /*net protocl*/
    u_long              connIndex;          /*sock index with the server*/

    netconnection       *prev,*next;        /*du link list ptr*/

    SOCKET_LIST_INDEX   list_index;         /*list index*/

    smart_lock          *opLock;            /*op lock*/
    user_token          *token;             /*user token*/

    netconnection()
    {
        sockfd = 0;
        OperationType = OP_INVALID;
        CurrentEvent = EVENT_INVALID;
        socket_state = S_CLOSE;
        iobuf = NULL;
        ctr_flag = false;
        events = 0;

        timeLastAction = time(NULL);
        timeConnBegin = time(NULL);
        erroCode = INVALID_ERROR;
        net_protocl = NET_TCP;
        connIndex = 0;

        prev = NULL;
        next = NULL;

        list_index = S_FREE_LIST;

        opLock = NULL;
        token = NULL;
    }
};


class connect_pool
{
public:
    connect_pool();
    ~connect_pool();

    int init_conn_pool(int init_count =DFLT_MIN_CONN_SIZ );

    int alloc_connection(netconnection *&pconn);
    int free_connection(netconnection *pconn);

    int get_free_socket_size();
    int get_total_socket_size();

    /*conn list and wait list swap*/
    int switch_to_wait_list(netconnection *pconn);
    int switch_to_conn_list(netconnection *pconn);

    /*conn list */
    link_list <netconnection> conn_list;
    link_list <netconnection> wait_list;
    smart_lock   conn_pool_lock;
    smart_lock   wait_pool_lock;

    /*memory buf pool */
    io_buf  mempool;

protected:
    void init_netconnection(netconnection * pconn);
    int   add_netconnection_pool();

private:
    int total_count;
    long conn_index;
    link_list <netconnection> free_list;
    int default_int_count;
};

#endif /* CONNECT_POOL_H_ */
